/*-----------------------------------------------------------------------------
	The contents of this file are subject to the Mozilla Public License
	Version 1.1 (the "License"); you may not use this file except in
	compliance with the License. You may obtain a copy of the License at
	http://www.mozilla.org/MPL/
	
	Software distributed under the License is distributed on an "AS IS"
	basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
	License for the specific language governing rights and limitations
	under the License.
	
	The Original Code is Fever Framework code.
	
	The Initial Developer of the Original Code is Romain Ecarnot.
	Portions created by Initial Developer are Copyright (C) 2006
	the Initial Developer. All Rights Reserved.
	
	Contributor(s):
	
	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
-----------------------------------------------------------------------------*/

import com.bourre.data.collections.IndexedArray;
import com.bourre.medias.sound.MixSoundFactory;

import fever.conf.ConfDebug;
import fever.data.libs.SoundFactoryLocator;
import fever.log.FeverDebug;
import fever.utils.Stringifier;

/**
 * Fever sound factory manager.
 * 
 * <p>Allow to switch between defined sound factories.
 * 
 * <p>Declared sound factories in configuration file :
 * {@code 
 *   <sounds>
 *     <factory id="interface" url="interface.swf" ref="click" manager="true" run="true" />
 *     <factory id="interface2" url="interface2.swf" ref="click" manager="true" />
 *   </sounds> 
 * }
 * <br />The {@code manager} attribute must be set to {@code true} to enable factory to 
 * be managed.
 * {@code run} attribute define if factory must be loaded at startup or not. Default use the 
 * first factory added to manager.
 * 
 * <p>then use the manager ( statics method ) to load factory you want
 * {@code
 *   AppSoundFactory.load( 'interface2' );
 *   AppSoundFactory.getSoundFactory().getSound( 'click' ).start();
 * }
 * 
 * <p>Of course, all managed factories must have the sounds references to play nice.<br />
 * Sounds library runtime switching !
 * 
 * @author Romain Ecarnot
 */
class fever.medias.sound.AppSoundFactory extends MixSoundFactory
{
	//-------------------------------------------------------------------------
	// Private properties
	//-------------------------------------------------------------------------
	
	private static var _a : IndexedArray = new IndexedArray();
	private static var _current : String;
	private static var _instance : AppSoundFactory;
	 
	private var _name : String;
	private var _soundsRef : Array;
	
		
	//-------------------------------------------------------------------------
	// Public API
	//-------------------------------------------------------------------------
	
	/**
	 * Returns unique {@link AppSoundFactory} instance.
	 */
	public static function getInstance() : AppSoundFactory
	{
		if( !_instance ) _instance = new AppSoundFactory();
		return _instance;	
	}
	
	/**
	 * Adds {@link AppSoundFactory} factory named {@code name} in repository 
	 * manager.
	 * 
	 * <p>After, you can switch factory using {@link #load()} method.
	 */
	public static function register( name : String ) : Boolean
	{
		var sf : AppSoundFactory = SoundFactoryLocator.getSoundFactory( name );
		if( sf )
		{
			var first : Boolean = _a.isEmpty();
			if( _a.push( name ) )
			{
				ConfDebug.DEBUG( 'SoundFactory ' + name + ' is managed' );
				
				if( first ) _current = name;
			}
			else return false;
		}
		return false;
	}
	
	/**
	 * Unregisters factory from manager.
	 */
	public static function unregister( name : String ) : Void
	{
		_a.remove( name );	
	}
	
	/**
	 * Sets {@link AppSoundFactory} named {@code name} as current 
	 * sound factory.
	 */
	public static function load( name : String ) : Void
	{
		if( _a.objectExists( name ) )
		{
			_current = name;
		}
		else FeverDebug.ERROR( 'Sound factory named ' + name + ' is not under manager control' );
	}
	
	/**
	 * Shortcut to start passed-in {@code soundID} in current factory.
	 */
	public static function play( soundID : String ) : Void
	{
		getSoundFactory().getSound( soundID ).start();	
	}
	
	/**
	 * Shortcut to start passed-in {@code soundID} in current factory.<br />
	 * Loop mode.
	 */
	public static function loop( soundID : String ) : Void
	{
		getSoundFactory().playSoundLoop( soundID );	
	}
	
	/**
	 * Returns current sound factory.
	 */
	public static function getSoundFactory() : AppSoundFactory
	{
		return SoundFactoryLocator.getSoundFactory( _current );	
	}
	
	/**
	 * Returns registred sound factory id list.
	 */
	public static function getSoundFactoryList() : Array
	{
		return _a.concat();	
	}
	
	/**
	 * Constructor.
	 */
	public function AppSoundFactory( factoryName : String )
	{
		super();
		
		_name = ( factoryName ) ? factoryName : 'default';
	}
	
	/**
	 * Overrides SoundFactory.getSound() method to log an error message 
	 * if passed-in {@code id} sound not exist in factory.
	 */
	public function getSound( id : String ) : Sound 
	{ 
		if( _oSounds[ id ] != undefined )
		{
			return _bIsOn ? _oSounds[id] : _noSound;
		}
		else
		{
			FeverDebug.ERROR( 'sound id [ ' + id + ' ] is not defined in ' + _name + ' factory' );
			return _noSound;	
		}
	}
	
	/**
	 * Returns {@code true} if passed-in {@code soundID} is registred into 
	 * current sound factory.
	 */
	public function hasSound( soundID : String ) : Boolean
	{
		return ( _oSounds[ soundID ] != undefined );	
	}
	
	/**
	 * Returns string representation.
	 */
	public function toString() : String
	{
		return Stringifier.parse( this );
	}
}